import { createSignal, onMount, onCleanup, type Component } from "solid-js";
import style from "./App.module.scss";
import { timestampToTime } from "./timer";
import TimeInput from "./components/TimeInput";
import UsageTip from "./components/UsageTip";
import TimerDisplay from "./components/TimerDisplay";
import ThemeSelector from "./components/ThemeSelector";
import ModeSelector from "./components/ModeSelector";
import ActionButtons from "./components/ActionButtons";

// 定义计时模式的类型
type Mode = "countup" | "countdown" | "current" | "alarm";
// 定义主题的类型
type Theme = "light" | "dark" | "neon" | "pastel" | "deepDark" | "pureWhite" | "cute";

// 自动对所有时区进行分组
const allTimezones = Intl.supportedValuesOf("timeZone");
const timezoneGroups: Record<string, string[]> = {};
allTimezones.forEach((timezone) => {
  const [continent] = timezone.split("/");
  if (!timezoneGroups[continent]) {
    timezoneGroups[continent] = [];
  }
  timezoneGroups[continent].push(timezone);
});

// 定义时区分组的键类型
type TimezoneGroupKeys = keyof typeof timezoneGroups;

// 新增独立变量用于主计时器，放在最顶部，确保全局可访问
let mainInterval: any = 0;

/**
 * 主应用组件
 */
const App: Component = () => {
  // 基础状态信号
  const [mode, setMode] = createSignal<Mode>((localStorage.getItem("mode") as Mode) || "countup");
  const [running, setRunning] = createSignal(false);
  const [isFullscreen, setIsFullscreen] = createSignal(false);
  const [showOptions, setShowOptions] = createSignal(true);

  // 时间相关信号
  const [countupTime, setCountupTime] = createSignal(Number(localStorage.getItem("countupTime")) || 0);
  const [countdownTime, setCountdownTime] = createSignal(Number(localStorage.getItem("countdownTime")) || 0);
  const [countdownInitial, setCountdownInitial] = createSignal(Number(localStorage.getItem("countdownInitial")) || 0);
  const [targetTime, setTargetTime] = createSignal(Number(localStorage.getItem("targetTime")) || 0);
  const [now, setNow] = createSignal(Date.now());

  // 创建信号来存储当前时区，默认从 localStorage 读取，若不存在则为系统默认时区
  const [timezone, setTimezone] = createSignal<string>(localStorage.getItem("timezone") || Intl.DateTimeFormat().resolvedOptions().timeZone);
  // 创建信号来存储当前选中的时区分组，默认为 'Asia'
  const [selectedGroup, setSelectedGroup] = createSignal<TimezoneGroupKeys>("Asia");
  // 创建信号来存储当前主题，默认从 localStorage 读取，若不存在则为 'light'
  const [theme, setTheme] = createSignal<Theme>((localStorage.getItem("theme") as Theme) || "light");
  // 创建信号来存储是否显示使用提示，默认根据 localStorage 中的 hasSeenUsageTip 决定
  const [showUsageTip, setShowUsageTip] = createSignal<boolean>(!localStorage.getItem("hasSeenUsageTip"));
  // 存储非活动计时器的 ID
  let inactivityTimer: any = 0;
  // 使用 createSignal 替代 createRef，用于存储选项区域的 DOM 引用
  const [optionsRef, setOptionsRef] = createSignal<HTMLDivElement | null>(null);

  /**
   * 暂停计时
   * 清除主计时器并更新运行状态
   */
  const pause = () => {
    if (mainInterval) {
      clearInterval(mainInterval);
      mainInterval = 0;
      setRunning(false);
      saveConfig();
    }
  };

  // 当前时间显示
  const getCurrentTime = () => {
    const options: Intl.DateTimeFormatOptions = {
      hour: "2-digit",
      minute: "2-digit",
      second: "2-digit",
      timeZone: timezone(),
    };
    return new Date(now()).toLocaleTimeString(undefined, options);
  };

  // 获取当前模式的时间
  const getCurrentModeTime = () => {
    switch (mode()) {
      case "countup":
        return countupTime();
      case "countdown":
        return countdownTime();
      case "alarm": {
        const currentTime = Math.floor(now() / 1000); // 使用 now() 确保实时性
        const target = targetTime();
        if (target === 0) return 0; // 未设置目标时间时返回 0
        const remaining = target - currentTime;
        if (remaining <= 0) {
          const nextTarget = target + 24 * 3600; // 推迟到下一天
          setTargetTime(nextTarget);
          return nextTarget - currentTime;
        }
        return remaining;
      }
      default:
        return 0;
    }
  };

  // 保存当前配置
  const saveConfig = () => {
    localStorage.setItem("mode", mode());
    localStorage.setItem("countupTime", String(countupTime()));
    localStorage.setItem("countdownTime", String(countdownTime()));
    localStorage.setItem("countdownInitial", String(countdownInitial()));
    localStorage.setItem("targetTime", String(targetTime()));
    localStorage.setItem("timezone", timezone());
    localStorage.setItem("running", String(running()));
    localStorage.setItem("theme", theme()); // 添加主题保存
  };

  // 修改模式切换处理函数
  const handleModeChange = (newMode: Mode) => {
    pause();
    setMode(newMode);
  
    switch (newMode) {
      case "current":
        start();
        break;
      case "countup":
        // 保持现有的 countupTime
        break;
      case "countdown":
        setCountdownTime(countdownInitial());
        break;
      case "alarm":
        // 确保目标时间正确设置
        const currentTime = Math.floor(Date.now() / 1000);
        if (targetTime() <= currentTime) {
          const now = new Date();
          let targetDate = new Date(targetTime() * 1000);
          targetDate.setDate(targetDate.getDate() + 1);
          setTargetTime(Math.floor(targetDate.getTime() / 1000));
        }
        break;
    }
    saveConfig();
  };

  // 开始计时
  function start() {
    if (mainInterval) return; // 防止重复启动
    setRunning(true);
    setNow(Date.now());
  
    mainInterval = setInterval(() => {
      const currentTime = Date.now();
      setNow(currentTime);
  
      switch (mode()) {
        case "countup":
          setCountupTime(t => t + 1);
          break;
        case "countdown":
          setCountdownTime(t => {
            if (t <= 0) {
              pause();
              return countdownInitial();
            }
            return t - 1;
          });
          break;
        case "alarm":
          const nowSeconds = Math.floor(currentTime / 1000);
          const target = targetTime();
          if (nowSeconds >= target && target !== 0) { // 检查目标时间是否有效
            const nextDate = new Date(target * 1000);
            nextDate.setDate(nextDate.getDate() + 1);
            const nextTarget = Math.floor(nextDate.getTime() / 1000);
            setTargetTime(nextTarget);
          }
          break;
        case "current":
          // 当前时间模式无需额外逻辑，依赖 now() 更新
          break;
      }
      saveConfig();
    }, 1000);
  }

  // 重置计时
  const reset = () => {
    switch (mode()) {
      case "countup":
        setCountupTime(0);
        break;
      case "countdown":
        setCountdownTime(countdownInitial());
        break;
      case "alarm":
        setTargetTime(0);
        break;
    }
    pause();
    saveConfig();
  };

  // 修改全屏处理函数
  const resetInactivityTimer = (e?: Event) => {
    clearTimeout(inactivityTimer);
    
    // 检查是否正在操作选择框
    if (e?.target instanceof HTMLSelectElement) {
      return;
    }
    
    inactivityTimer = setTimeout(() => {
      // 只在计时运行中或当前时间模式时才进入全屏
      if (running() || mode() === "current") {
        enterFullscreen();
        setShowOptions(false);
      }
    }, 5000);
  };

  /**
   * 进入全屏模式
   * 尝试将文档根元素设置为全屏模式，并更新 isFullscreen 信号
   */
  const enterFullscreen = () => {
    const element = document.documentElement;
    try {
      if (element.requestFullscreen) {
        element.requestFullscreen();
      } else if ((element as any).webkitRequestFullscreen) {
        // Safari 支持
        (element as any).webkitRequestFullscreen();
      } else if ((element as any).webkitEnterFullscreen) { 
        // iOS Safari 支持
        (element as any).webkitEnterFullscreen();
      }
      setIsFullscreen(true);
    } catch (error) {
      console.warn("Fullscreen not supported:", error);
    }
  };

  /**
   * 退出全屏模式
   * 尝试退出全屏模式，并更新 isFullscreen 和 showOptions 信号
   */
  const exitFullscreen = () => {
    try {
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if ((document as any).webkitExitFullscreen) {
        (document as any).webkitExitFullscreen();
      } else if ((document as any).webkitCancelFullScreen) {
        (document as any).webkitCancelFullScreen();
      }
      setIsFullscreen(false);
      setShowOptions(true);
    } catch (error) {
      console.warn("Exit fullscreen failed:", error);
    }
  };

  /**
   * 处理点击事件
   * 当处于全屏模式且点击位置不在选项区域内时，显示选项
   * @param e - 鼠标点击事件对象
   */
  // 处理点击事件，当处于全屏模式且点击空白处时，退出全屏并显示选项
  const handleClick = (e: MouseEvent) => {
    const optionsElement = optionsRef();
    if (isFullscreen() && !optionsElement?.contains(e.target as Node)) {
      exitFullscreen();
      setShowOptions(true);
    }
  };

  // 修改时间输入处理函数
  const handleTimeInput = (e: Event) => {
    const input = e.target as HTMLInputElement;
    const [hours, minutes, seconds] = input.value.split(":").map(Number);
  
    if (input.dataset.isAlarm === "true") {
      const now = new Date();
      const targetDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
      targetDate.setHours(hours || 0);
      targetDate.setMinutes(minutes || 0);
      targetDate.setSeconds(seconds || 0);
  
      // 如果目标时间已过去，推迟到下一天
      if (targetDate <= now) {
        targetDate.setDate(targetDate.getDate() + 1);
      }
  
      const targetSeconds = Math.floor(targetDate.getTime() / 1000);
      setTargetTime(targetSeconds);
      saveConfig();
    }
    setNow(Date.now());
  };

  /**
   * 关闭使用提示
   * 更新 showUsageTip 信号并将 hasSeenUsageTip 保存到 localStorage
   */
  const closeUsageTip = () => {
    setShowUsageTip(false);
    localStorage.setItem("hasSeenUsageTip", "true");
  };

  /**
   * 判断是否应禁用重置按钮
   * 根据当前模式和时间状态判断是否禁用重置按钮
   * @returns {boolean} - 如果应禁用则返回 true，否则返回 false
   */
  const shouldDisableReset = () => {
    const current = getCurrentModeTime();
    switch (mode()) {
      case "countup":
        return current === 0;
      case "countdown":
        return current === countdownInitial();
      case "alarm":
        return targetTime() === 0;
      default:
        return true;
    }
  };

  // 修改时间显示格式化函数
  const formatTimeForInput = (seconds: number) => {
    if (mode() === "alarm") {
      if (seconds === 0) return "00:00:00"; // 未设置时显示默认值
      const date = new Date(seconds * 1000);
      return date.toLocaleTimeString("en-US", { 
        hour12: false,
        timeZone: timezone()
      }).slice(0, 8);
    }

    // 对于倒计时模式，支持更大的时间范围
    const hours = Math.floor(seconds / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    const secs = seconds % 60;
    return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
  };

  const timerContent = () => {
    switch (mode()) {
      case "countup":
      case "countdown":
        return timestampToTime(getCurrentModeTime());
      case "current":
        return getCurrentTime();
      case "alarm":
        return timestampToTime(getCurrentModeTime());
      default:
        return "";
    }
  };

  // 添加键盘事件处理函数
  const handleKeyPress = (e: KeyboardEvent) => {
    // 如果是在输入框中按键，不处理
    if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
      return;
    }

    // 空格键控制开始/暂停
    if (e.code === "Space") {
      e.preventDefault(); // 防止页面滚动
      if (mode() !== "current") {
        if (running()) {
          pause();
        } else {
          start();
        }
      }
    }

    // R键重置
    if (e.code === "KeyR") {
      e.preventDefault();
      if (mode() !== "current" && !shouldDisableReset()) {
        reset();
      }
    }
  };

  const checkFullscreenStatus = () => {
    const isFullscreenNow = !!(
      document.fullscreenElement ||
      (document as any).webkitFullscreenElement ||
      (document as any).webkitCurrentFullScreenElement
    );
    setIsFullscreen(isFullscreenNow);
  };

  onMount(() => {
    document.addEventListener("mousemove", resetInactivityTimer);
    document.addEventListener("keypress", resetInactivityTimer);
    document.addEventListener("keydown", handleKeyPress); // 添加键盘事件监听
    window.addEventListener("click", handleClick);

    // 添加全屏变化事件监听
    document.addEventListener("fullscreenchange", checkFullscreenStatus);
    document.addEventListener("webkitfullscreenchange", checkFullscreenStatus);

    // 检测是否支持全屏
    const element = document.documentElement;
    const fullscreenEnabled = !!(
      element.requestFullscreen ||
      (element as any).webkitRequestFullscreen ||
      (element as any).webkitEnterFullscreen
    );

    if (!fullscreenEnabled) {
      console.warn("Fullscreen not supported on this device");
    }

    // 如果之前在运行，恢复计时
    if (localStorage.getItem("running") === "true") {
      start();
    }
  });

  onCleanup(() => {
    document.removeEventListener("mousemove", resetInactivityTimer);
    document.removeEventListener("keypress", resetInactivityTimer);
    document.removeEventListener("keydown", handleKeyPress); // 移除键盘事件监听
    window.removeEventListener("click", handleClick);
    document.removeEventListener("fullscreenchange", checkFullscreenStatus);
    document.removeEventListener("webkitfullscreenchange", checkFullscreenStatus);
    clearInterval(mainInterval);
    clearTimeout(inactivityTimer);
  });

  return (
    <div class={`${style.container} ${style[theme()]} ${isFullscreen() ? style.fullscreen : ""}`}>
      {showUsageTip() && <UsageTip onClose={closeUsageTip} />}
      <TimerDisplay content={timerContent()} />
      <div ref={(el) => setOptionsRef(el)}>
        {showOptions() && (
          <>
            <ThemeSelector currentTheme={theme()} onThemeChange={(newTheme) => {
              setTheme(newTheme);
              saveConfig();
            }} />
            <ModeSelector
              mode={mode()}
              onModeChange={(newMode) => {
                pause();
                setMode(newMode);
                clearInterval(inactivityTimer);
                handleModeChange(newMode);
              }}
              countdownInitial={countdownInitial()}
              onCountdownInitialChange={(value) => {
                setCountdownInitial(value);
                setCountdownTime(value);
                saveConfig();
              }}
              targetTime={targetTime()}
              onTargetTimeChange={setTargetTime}
              formatTimeForInput={formatTimeForInput}
              handleTimeInput={handleTimeInput}
            />
            <ActionButtons
              running={running()}
              mode={mode()}
              countdownTime={countdownTime()}
              targetTime={targetTime()}
              now={now()}
              start={start}
              pause={pause}
              reset={reset}
              shouldDisableReset={shouldDisableReset}
            />
            <div class={style.action}>
              <select
                onChange={(e) => {
                  const select = e.target as HTMLSelectElement;
                  setTimezone(select.value);
                  saveConfig();
                }}
                value={timezone()}
              >
                {timezoneGroups[selectedGroup()].map((tz) => (
                  <option value={tz}>{tz}</option>
                ))}
              </select>
              <select
                onChange={(e) => {
                  const select = e.target as HTMLSelectElement;
                  setSelectedGroup(select.value as TimezoneGroupKeys);
                  // 切换分组时，如果当前时区不在新分组中，则默认选择新分组的第一个时区
                  if (!timezoneGroups[select.value as TimezoneGroupKeys].includes(timezone())) {
                    setTimezone(timezoneGroups[select.value as TimezoneGroupKeys][0]);
                  }
                  saveConfig();
                }}
                value={selectedGroup()}
              >
                {Object.keys(timezoneGroups).map((group) => (
                  <option value={group}>{group}</option>
                ))}
              </select>
            </div>
          </>
        )}
      </div>
    </div>
  );
};

export default App;

